﻿using Cobra11Undercover.Material;
using Cobra11Undercover.Shaders;
using Cobra11Undercover.Shaders.C11Undercover;
using Cobra11Undercover.Shaders.C11UndercoverShaders;
using Cobra11Undercover.Shaders.Wr2Shaders;
using Engine.FileFormats3D.C11Undercover;
using SharpDX.Direct3D11;
using System.Collections.Generic;

namespace Engine.Graphics.Shaders
{
    public class C11UndercoverShaderArray : IShaderArray
    {
        #region Private Fields

        private Shaders.Wr2Shaders.MaterialColorShader colorShader;
        private Engine engine;
        private Material000 material000;
        private Material016 material016;
        private Material017 material017;
        private Material032 material032;
        private Material048 material048;
        private Material064 material064;
        private Material080 material080;
        private Material096 material096;
        private Material112 material112;
        private Material128 material128;

        //Material144 material144;
        //Material160 material160;
        private Material176 material176;

        //Material192 material192;
        private Material208 material208;

        private Material224 material224;
        private Material240 material240;
        private Material272 material272;
        private Material288 material288;
        private Material304 material304;
        private Material320 material320;
        private Material336 material336;
        private Material352 material352;
        private Material368 material368;
        private Material384 material384;
        private Material400 material400;
        private Material416 material416;
        private Material432 material432;
        private List<ISetShaderValues> registeredShaders;
        private ShaderManager shaderManger;
        private string shaderpath;
        private StandardEffect standardEffect;
        private VertexColorShader vertexColorShader;

        #endregion Private Fields

        #region Public Constructors

        public C11UndercoverShaderArray(Engine device, string shaderpath, ShaderManager shaderManager)
        {
            this.shaderpath = shaderpath + "\\C11Undercover\\";
            this.registeredShaders = new List<ISetShaderValues>();
            this.engine = device;
            LoadShaders(this.shaderpath, device, shaderManager);

            this.GlobalShader = EnumGlobalShader.Material;
        }

        #endregion Public Constructors

        #region Public Methods

        internal EnumGlobalShader GlobalShader { get; set; }

        void IShaderArray.Dispose()
        {
            throw new System.NotImplementedException();
        }

        public List<ISetShaderValues> GetRegisteredShaders()
        {
            return this.registeredShaders;
        }

        public void LoadShaders(string shaderPath, Engine engine, ShaderManager shaderManager)
        {
            Device device = engine.Grafic.Device;
            this.shaderManger = shaderManager ?? throw new System.Exception("Shadermanager shouldn´t be 'null'!");

            //Load

            this.vertexColorShader = new VertexColorShader(device, this.shaderpath, this.shaderManger);

            this.standardEffect = new StandardEffect(device, shaderManager);
            this.material000 = new Material000(device, shaderPath, shaderManager);
            this.material016 = new Material016(device, shaderPath, shaderManager);
            this.material017 = new Material017(device, shaderPath, shaderManager);
            this.material032 = new Material032(device, shaderPath, shaderManager);
            this.material048 = new Material048(device, shaderPath, shaderManager);
            this.material064 = new Material064(device, shaderPath, shaderManager);
            this.material080 = new Material080(device, shaderPath, shaderManager);
            this.material096 = new Material096(device, shaderPath, shaderManager);
            this.material112 = new Material112(device, shaderPath, shaderManager);
            this.material128 = new Material128(device, shaderPath, shaderManager);
            this.material176 = new Material176(device, shaderPath, shaderManager);
            this.material208 = new Material208(device, shaderPath, shaderManager);
            this.material224 = new Material224(device, shaderPath, shaderManager);
            this.material240 = new Material240(device, shaderPath, shaderManager);
            this.material272 = new Material272(device, shaderPath, shaderManager);
            this.material288 = new Material288(device, shaderPath, shaderManager);
            this.material304 = new Material304(device, shaderPath, shaderManager);
            this.material320 = new Material320(device, shaderPath, shaderManager);
            this.material336 = new Material336(device, shaderPath, shaderManager);
            this.material352 = new Material352(device, shaderPath, shaderManager);
            this.material368 = new Material368(device, shaderPath, shaderManager);
            this.material384 = new Material384(device, shaderPath, shaderManager);
            this.material400 = new Material400(device, shaderPath, shaderManager);
            this.material416 = new Material416(device, shaderPath, shaderManager);
            this.material432 = new Material432(device, shaderPath, shaderManager);
            this.colorShader = new Wr2Shaders.MaterialColorShader(device, shaderPath, shaderManager);

            this.registeredShaders.Clear();
            this.registeredShaders.Add(this.material000);
            this.registeredShaders.Add(this.standardEffect);
            this.registeredShaders.Add(this.material016);
            this.registeredShaders.Add(this.material017);
            this.registeredShaders.Add(this.material032);
            this.registeredShaders.Add(this.material048);
            this.registeredShaders.Add(this.material064);
            this.registeredShaders.Add(this.material080);
            this.registeredShaders.Add(this.material096);
            this.registeredShaders.Add(this.material112);
            this.registeredShaders.Add(this.material128);
            //this.registeredShaders.Add(this.material144);
            //this.registeredShaders.Add(this.material160);
            this.registeredShaders.Add(this.material176);
            //this.registeredShaders.Add(this.material192);
            this.registeredShaders.Add(this.material208);
            this.registeredShaders.Add(this.material224);
            this.registeredShaders.Add(this.material240);
            this.registeredShaders.Add(this.material272);
            this.registeredShaders.Add(this.material288);
            this.registeredShaders.Add(this.material304);
            this.registeredShaders.Add(this.material320);
            this.registeredShaders.Add(this.material336);
            this.registeredShaders.Add(this.material352);
            this.registeredShaders.Add(this.material368);
            this.registeredShaders.Add(this.material384);
            this.registeredShaders.Add(this.material400);
            this.registeredShaders.Add(this.material416);
            this.registeredShaders.Add(this.material432);
            this.registeredShaders.Add(this.colorShader);
        }

        void IShaderArray.ReloadShaders(ShaderManager shaderManager)
        {
            LoadShaders(shaderManager.ShaderDirectory + "\\C11Undercover\\", this.engine, shaderManager);
            this.registeredShaders.AddRange(GetRegisteredShaders());
        }

        public void ReloadShaders()
        {
            throw new System.NotImplementedException();
        }

        public ShaderBase SetEffectValues(int materialID, MaterialManager materialManager)
        {
            switch (GlobalShader)
            {
                case EnumGlobalShader.Material:
                    // material = materialManager.GetMaterial(10);
                    C11Material material = (C11Material)materialManager.GetMaterialForGame(materialID);

                    //switch (EnumC11UndercoverMappingMode.Material32)
                    switch ((EnumC11UndercoverMappingMode)material.MappingMode)
                    {
                        case EnumC11UndercoverMappingMode.Material00:
                        case (EnumC11UndercoverMappingMode)1:
                        case (EnumC11UndercoverMappingMode)2:
                            this.material000.SetProperties(materialID, materialManager);
                            return this.material000.Effect;

                        case EnumC11UndercoverMappingMode.Material16:
                            this.material016.SetProperties(materialID, materialManager);
                            return this.material016.Effect;

                        case EnumC11UndercoverMappingMode.Material17:
                            this.material017.SetProperties(materialID, materialManager);
                            return this.material017.Effect;

                        case EnumC11UndercoverMappingMode.Material32:
                        case (EnumC11UndercoverMappingMode)33:
                            this.material032.SetProperties(materialID, materialManager);
                            return this.material032.Effect;

                        case EnumC11UndercoverMappingMode.Material48:
                            this.material048.SetProperties(materialID, materialManager);
                            return this.material048.Effect;

                        case EnumC11UndercoverMappingMode.Material64:
                            this.material064.SetProperties(materialID, materialManager);
                            return this.material064.Effect;

                        case EnumC11UndercoverMappingMode.Material80:
                            this.material080.SetProperties(materialID, materialManager);
                            return this.material080.Effect;

                        case EnumC11UndercoverMappingMode.Material96:
                            this.material096.SetProperties(materialID, materialManager);
                            return this.material096.Effect;

                        case EnumC11UndercoverMappingMode.Material112:
                            this.material112.SetProperties(materialID, materialManager);
                            return this.material112.Effect;

                        case EnumC11UndercoverMappingMode.Material128:
                            this.material128.SetProperties(materialID, materialManager);
                            return this.material128.Effect;

                        ////case EnumC11UndercoverMappingMode.material144:
                        ////    material144.SetProperties(material, materialManager);
                        ////    return material144.Effect;

                        ////case EnumC11UndercoverMappingMode.material160:
                        ////    material160.SetProperties(material, materialManager);
                        ////    return material160.Effect;

                        case EnumC11UndercoverMappingMode.Material176:
                            this.material176.SetProperties(materialID, materialManager);
                            return this.material176.Effect;

                        ////case EnumC11UndercoverMappingMode.material192:
                        ////    material192.SetProperties(material, materialManager);
                        ////    return material192.Effect;

                        case EnumC11UndercoverMappingMode.Material208:
                            this.material208.SetProperties(materialID, materialManager);
                            return this.material208.Effect;

                        case EnumC11UndercoverMappingMode.Material224:
                            this.material224.SetProperties(materialID, materialManager);
                            return this.material224.Effect;

                        case EnumC11UndercoverMappingMode.Material240:
                            this.material240.SetProperties(materialID, materialManager);
                            return this.material240.Effect;

                        case EnumC11UndercoverMappingMode.Material272:
                            this.material272.SetProperties(materialID, materialManager);
                            return this.material272.Effect;

                        case EnumC11UndercoverMappingMode.Material288:
                            this.material288.SetProperties(materialID, materialManager);
                            return this.material288.Effect;

                        case EnumC11UndercoverMappingMode.Material304:
                            this.material304.SetProperties(materialID, materialManager);
                            return this.material304.Effect;

                        case EnumC11UndercoverMappingMode.Material320:
                            this.material320.SetProperties(materialID, materialManager);
                            return this.material320.Effect;

                        case EnumC11UndercoverMappingMode.Material336:
                            this.material336.SetProperties(materialID, materialManager);
                            return this.material336.Effect;

                        case EnumC11UndercoverMappingMode.Material352:
                            this.material352.SetProperties(materialID, materialManager);
                            return this.material352.Effect;

                        case EnumC11UndercoverMappingMode.Material368:
                            this.material368.SetProperties(materialID, materialManager);
                            return this.material368.Effect;

                        case EnumC11UndercoverMappingMode.Material384:
                            this.material384.SetProperties(materialID, materialManager);
                            return this.material384.Effect;

                        case EnumC11UndercoverMappingMode.Material400:
                            this.material400.SetProperties(materialID, materialManager);
                            return this.material400.Effect;

                        case EnumC11UndercoverMappingMode.Material416: // Lights in tunnel. but doesent work correct
                            this.material416.SetProperties(materialID, materialManager);
                            return this.material416.Effect;

                        case EnumC11UndercoverMappingMode.Material432: // Lights in tunnel. but doesent work correct
                            this.material432.SetProperties(materialID, materialManager);
                            return this.material432.Effect;

                        default:
                            this.material016.SetProperties(materialID, materialManager);
                            return this.material016.Effect;
                    }
                case EnumGlobalShader.VertexColor:
                    //vertexColorShader.SetProperties(0, materialManager);
                    return this.vertexColorShader.effect;

                default:
                    throw new System.Exception("Global Shader Not Implemented: " + this.GlobalShader.ToString());
            }
        }

        #endregion Public Methods

        #region Internal Methods

        internal void Dispose()
        {
            foreach (var item in this.registeredShaders)
            {
                item.Dispose();
            }
            this.registeredShaders.Clear();
        }

        internal void ReloadShaders(ShaderManager shaderManager)
        {
            LoadShaders(this.shaderpath, this.engine, shaderManager);
        }

        #endregion Internal Methods
    }
}